

#ifndef __FAST_LOCK_H__
#define __FAST_LOCK_H__

#ifdef __cplusplus
extern "C" {
#endif

typedef DWORD FAST_LOCK;
#define FAST_LOCK_FREE_VAL 0x45455246	// "FREE"
#define FAST_LOCK_LOCK_VAL 0x4B434F4C	// "LOCK"
#define INIT_FAST_LOCK(fast_lock) (fast_lock=FAST_LOCK_FREE_VAL)
#define INIT_FAST_LOCK_DECLEAR(fast_lock) FAST_LOCK fast_lock=FAST_LOCK_FREE_VAL
#define FAST_LOCK_WAIT_PRIORITY	250


// set dwNewVal to *pAddr and return the old value of *pAddr
extern DWORD Swap(DWORD* pdwAddr, DWORD dwNewVal);

#ifdef KERNEL_LIB
__inline BOOL FastLock_Lock(FAST_LOCK* pFastLock, DWORD dwMs)
{
	*pFastLock=INTERRUPTS_ENABLE(FALSE);
	return TRUE;
}
__inline VOID FastLock_Release(FAST_LOCK* pFastLock)
{
	INTERRUPTS_ENABLE(*pFastLock);
}
#else
BOOL FastLock_Lock(FAST_LOCK* pFastLock, DWORD dwMs);
__inline VOID FastLock_Release(FAST_LOCK* pFastLock)
{
	*pFastLock=FAST_LOCK_FREE_VAL;
}
#endif	//#indef KERNEL_LIB
	

#if defined(_FAST_LOCK_IMP)|defined(KEN_LIB_IMP)

#ifndef USE_ASM_LIB
DWORD Swap(DWORD* pdwAddr, DWORD dwNewVal)
{
// only for compile, when excute raise exception	
	*((DWORD*) 0)=0;
	return 0;
}
#endif


#ifndef KERNEL_LIB
DWORD g_dwFastLockLowTimes=0;
DWORD g_dwFastLockTryTimes=0;
BOOL FastLock_Lock(FAST_LOCK* pFastLock, DWORD dwMs)
{
	BOOL fLowPriority=FALSE;
	DWORD dwOldPriority;
	HANDLE hThrd;
	DWORD dwStartTick, dwCurTick, dwDiff;
	BOOL fRet;

	do
	{
		if(FAST_LOCK_FREE_VAL==Swap(pFastLock, FAST_LOCK_LOCK_VAL))
		{
			fRet=TRUE;
			break;
		}

		g_dwFastLockTryTimes++;
		if(!fLowPriority)
		{
			hThrd=GetCurrentThread();
#ifdef UNDER_CE
			dwOldPriority=CeGetThreadPriority(hThrd);
			CeSetThreadPriority(hThrd, FAST_LOCK_WAIT_PRIORITY);
#else
			dwOldPriority=GetThreadPriority(hThrd);
			SetThreadPriority(hThrd, FAST_LOCK_WAIT_PRIORITY);
#endif
			dwStartTick=GetTickCount();
			fLowPriority=TRUE;
			g_dwFastLockLowTimes++;
		}
		else
		{
			dwCurTick=GetTickCount();
			if(dwCurTick>dwStartTick)
			{
				dwDiff=dwCurTick-dwStartTick;
			}
			else
			{
				dwDiff=dwStartTick-dwCurTick;
			}

			// time out
			if(dwDiff>=dwMs)
			{
				fRet=FALSE;
				break;
			}
//RETAILMSG(dwDiff>1000,(TEXT("FastLock_Get can't get lock for %d ms\r\n"), dwDiff));
		}
		
	}while(1);

	if(fLowPriority)
	{
#ifdef UNDER_CE
		CeSetThreadPriority(hThrd, dwOldPriority);
#else
		SetThreadPriority(hThrd, dwOldPriority);
#endif
	}

	return fRet;
}

#endif	//#ifndef KERNEL_LIB

#endif	//#if defined(_FAST_LOCK_IMP)|defined(KEN_LIB_IMP)


#ifdef __cplusplus
}
#endif


#endif	//#ifndef __FAST_LOCK_H__


